package com.dsiab.manageService.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.dsiab.manageService.entity.*;
import com.dsiab.manageService.mapper.AccountDao;
import com.dsiab.manageService.mapper.AdminDao;
import com.dsiab.manageService.mapper.NavigationDao;
import com.dsiab.manageService.mapper.PagesDao;
import com.dsiab.manageService.security.service.GetCurrentLoginUsername;
import com.dsiab.manageService.service.AccountService;
import com.dsiab.manageService.service.AdminService;
import com.dsiab.manageService.threads.PushThread;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class AdminServiceImpl implements AdminService {
//  @Autowired
//  MailSenderBoot mailSenderBoot;
  @Autowired
  AccountService accountService;
  @Autowired
  NavigationDao navigationDao;
  @Autowired
  AccountDao accountDao;
  @Autowired
  AdminDao adminDao;
  @Autowired
  GetCurrentLoginUsername getCurrentLoginUsername;
  @Autowired
  PagesDao pagesDao;
  @Autowired
  RedisTemplate redisTemplate;

  public Map getDetail(String id){
    PagesDto pagesDto;
    // 同时满足数字id跟随机数id
    if (id.indexOf("-") > 0){
      // 如果是uuid则通过Uuid查询
      pagesDto = pagesDao.getDetailByUUID(id);
    } else {
      pagesDto = pagesDao.getDetail(Integer.parseInt(id));
    }
    // 浏览量加1
    adminDao.updateViews(pagesDto);
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", pagesDto);
    return resultMap;
  };

  public Map getListByCatePage(PagesDto pagesDto){

    int cate = pagesDto.getCate();
    int page = pagesDto.getPage();
    int pageSize = pagesDto.getPageSize();

    Map<String, Object> resultMap = new HashMap<>();
    List<PagesDto> list;

    // 使用pageHelper分页
    PageInfo<PagesDto> pagesDtoPageInfo;
    // 通过字段排序
    PageHelper.startPage(page,pageSize,pagesDto.getOrderBy() + " " + pagesDto.getOrder());

    // 获取当前登录人
    String username = getCurrentLoginUsername.getUsername();

    if (cate > 0){
      list = adminDao.getListByCateByUserId(cate,page,username);
      pagesDtoPageInfo = new PageInfo<>(list);
    } else {
      if (username.equals("admin")){
        // 如果是管理员则查询所有数据,否则查当前登录人
        list =  adminDao.getAll(page);
        pagesDtoPageInfo = new PageInfo<>(list);
      } else {
        list =  adminDao.getAllByUsername(page,username);
        pagesDtoPageInfo = new PageInfo<>(list);
      }
    }

    resultMap.put("total", pagesDtoPageInfo.getTotal());
    resultMap.put("result", pagesDtoPageInfo.getList());
    return resultMap;
  };

  public void insertComment(CommentsDto commentsDto){
    pagesDao.insertComment(commentsDto);
    pagesDao.updateCommentNum(commentsDto);
    // 有新评论发送邮件通知
    Map siteInfo = accountDao.getSiteInfo();
//    mailSenderBoot.sendMail((String)siteInfo.get("siteEmail"), commentsDto.getUsername() +"发表了评论："+  commentsDto.getContent(), "评论通知");

  }

  public Map getUserListByPage(String page){

    Map<String, Object> resultMap = new HashMap<>();
    List<UserDto> list;
    // 使用pageHelper分页
    PageHelper.startPage(Integer.parseInt(page),10);
    list = accountService.getUserList(Integer.parseInt(page));
    PageInfo<UserDto> pagesDtoPageInfo = new PageInfo<>(list);

    resultMap.put("result", pagesDtoPageInfo.getList());
    resultMap.put("total", pagesDtoPageInfo.getTotal());
    return resultMap;
  };

  public Map getRoleList(){
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", accountDao.getRoleList());
    return resultMap;
  };

  public void updateRole(Map roleMap){
    List<Map> list = (List<Map>) roleMap.get("roleList");
    String username = (String)roleMap.get("username");
    // 更新角色前删除之前的角色
    accountDao.deleteRolesByUsername(username);
    for (Map map: list){
      accountDao.insertRole(username,(String) map.get("roleId"));
    }
  };

  public Map<String, Object> getNavList(Map map){
    Map<String, Object> resultMap = new HashMap<>();
    PageHelper.startPage((int)map.get("page"),(int)map.get("pageSize"));
    String cate = "";
    if (!map.get("cate").equals("")) {
      cate = String.valueOf(map.get("cate")) ;
    };
    List<NavigationDto> list = navigationDao.getAll(cate);
    PageInfo<NavigationDto> pagesDtoPageInfo = new PageInfo<>(list);
    resultMap.put("result", pagesDtoPageInfo.getList());
    resultMap.put("total", pagesDtoPageInfo.getTotal());
    return resultMap;
  };

  public int insertOne(PagesDto pagesDto) {
    pagesDto.setUid(UUID.randomUUID().toString());
    adminDao.insertOne(pagesDto);
    PushThread pushThread = new PushThread();
    pushThread.setPostId(pagesDto.getUid());
    Thread thread = new Thread(pushThread);
    thread.start();
    return pagesDto.getId();
  }

  public void batchDelPost(List ids) {
    String username = getCurrentLoginUsername.getUsername();
    adminDao.batchDelPost(ids,username);
  }

  public void delOne(int id) {
    String username = getCurrentLoginUsername.getUsername();
    // 更新文章前删除缓存
    try {
      redisTemplate.delete(String.valueOf(id));
    } catch (Exception e){
      log.error(e.toString());
    }
    //  管理员可以删除任何文章
    if (username.equals("admin")){
      adminDao.delOneByadmin(id);
    } else {
      adminDao.delOne(id, username);
    }
  }

  public int updateOne(PagesDto pagesDto) throws Exception {
    String createBy = adminDao.getCreateByid(pagesDto.getId());
    String username = getCurrentLoginUsername.getUsername();
    // 更新文章前删除缓存
    try {
      redisTemplate.delete(String.valueOf(pagesDto.getId()));
      redisTemplate.delete(String.valueOf(pagesDto.getUid()));
    } catch (Exception e){
      log.error(e.toString());
    }

    // 更新操作需判断当前内容是由本人创建
    if (!createBy.equals(username)){
      throw new Exception("无权更新");
    }
    adminDao.updateOne(pagesDto);
    PushThread pushThread = new PushThread();
    pushThread.setPostId(pagesDto.getUid());
    Thread thread = new Thread(pushThread);
    thread.start();
    return pagesDto.getId();
  }

  public void insertCate(CateDto cateDto) {
    // 获取当前登录人
    String username = getCurrentLoginUsername.getUsername();
    cateDto.setCreatedBy(username);
    adminDao.insertCate(cateDto);
  }

  public void updateCate(CateDto cateDto) {
    adminDao.updateCate(cateDto);
  }

  public void delCate(int id) {
    adminDao.delCate(id);
  }

  public void delComment(List ids) {
    adminDao.delComment(ids);
  }

  /**
   * 清除redis缓存
   */
  public void clearCache() {
    // 清楚所有redis缓存
    try {
      Set<String> keys = redisTemplate.keys("*");
      Iterator<String> iterator = keys.iterator();
      while (iterator.hasNext()){
        boolean res =  redisTemplate.delete(iterator.next());
        log.info("del-res",res);
      }
    } catch (Exception e){
      log.error(e.toString());
    }

  }

  public Object getCateList(){
    String createdBy = getCurrentLoginUsername.getUsername();
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", adminDao.getCate(createdBy));
    return resultMap;
  };

  /**
   * 新增专题
   * @param topicDto
   */
  public void insertTopic(TopicDto topicDto) {
    adminDao.insertTopic(topicDto);
  }

  /**
   * 更新专题名称
   * @param topicDto
   */
  public void updateTopic(TopicDto topicDto) {
    adminDao.updateTopic(topicDto);
  }

  /**
   * 查询专题列表
   * @return
   */
  public Object getTopicList(){
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", adminDao.getTopicList());
    return resultMap;
  };

  /**
   * 添加文章到专题
   * @param topicDto
   */
  public void addPostToTopic(TopicDto topicDto) {
    adminDao.addPostToTopic(topicDto);
  }

  /**
   * 查询专题详情列表
   * @param topicDto
   * @return
   */
  public Object getTopicDetailList(TopicDto topicDto){
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", adminDao.getTopicDetailList(topicDto));
    return resultMap;
  };

  /**
   * 删除专题
   * @param topicDto
   */
  public void deleteTopic(TopicDto topicDto) {
    adminDao.deleteTopic(topicDto);
  }

  /**
   * 删除专题文章
   * @param topicDto
   */
  public void deleteTopicDetail(TopicDto topicDto) {
    adminDao.deleteTopicDetail(topicDto);
  }

  /**
   * 查询回收站所有文章
   * @param pagesDto
   * @return
   */
  public Map getRecycleListByCatePage(PagesDto pagesDto){

    int page = pagesDto.getPage();
    int pageSize = pagesDto.getPageSize();

    Map<String, Object> resultMap = new HashMap<>();
    List<PagesDto> list;

    // 使用pageHelper分页
    PageInfo<PagesDto> pagesDtoPageInfo;
    PageHelper.startPage(page,pageSize);

    // 如果是管理员则查询所有数据,否则查当前登录人
    list =  adminDao.getRecycleAll(page);
    pagesDtoPageInfo = new PageInfo<>(list);

    resultMap.put("total", pagesDtoPageInfo.getTotal());
    resultMap.put("result", pagesDtoPageInfo.getList());
    return resultMap;
  };

  /**
   * 删除文章
   */
  public void deletePost(List ids) {
      adminDao.deletePost(ids);
  }

  public void insertMenu(MenuDto menuDto) {
    adminDao.insertMenu(menuDto);
  }

  public Map getMenuList(MenuDto menuDto){
    if(menuDto.getMenuId() > 0){
      List list = adminDao.getMenuListByParentId(menuDto.getMenuId());
      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("result", list);
      return resultMap;
    } else {
      List list = adminDao.getMenuList();
      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("result", list);
      return resultMap;
    }
  };

  public void updateMenu(MenuDto menuDto) {
    adminDao.updateMenu(menuDto);
  }

  public void deleteMenu(MenuDto menuDto) {
    adminDao.deleteMenu(menuDto);
  }

  public Map getMenus(){
    // 获取当前登录人
    String username = getCurrentLoginUsername.getUsername();
    // 用户可同时有多个角色
    List roleIdList = adminDao.getRoleIdByUserName(username);
    List<MenuDto> list = new ArrayList<>();
    for (int i = 0; i < roleIdList.size(); i++) {
      String roleId = (String)roleIdList.get(i);
      int rid = adminDao.getRIdByroleId(roleId);
      List tlist = adminDao.getAllMenusByRole(rid);
      list.addAll(tlist);
    }
    HashSet<MenuDto> set = new HashSet<MenuDto>(list.size());
    List<MenuDto> result = new ArrayList<MenuDto>(list.size());
    // 通过hashSet能够能添加来判断是否有重复数据
    for (MenuDto menuDto : list) {
      if (set.add(menuDto)) {
        result.add(menuDto);
      }
    }
    list.clear();
    list.addAll(result);

    List nList = new ArrayList();
    for (MenuDto menuDto: list){
      List<MenuDto> children = new ArrayList<>();
      for (int i = 0; i <list.size() ; i++) {
        MenuDto mDto = list.get(i);
        int pid = 0;
        if (mDto.getParentId() == null){
          continue;
        }
        pid = Integer.valueOf(mDto.getParentId());
        int mid = menuDto.getMenuId();
        // 设置一级菜单子菜单
        if (mid == pid){
          children.add(mDto);
        }
      }
      menuDto.setChildren(children);
      // 最外层取无parentId一层菜单
      if (menuDto.getParentId() == null){
        nList.add(menuDto);
      }
    }
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", nList);
    return resultMap;
  };

  public void updateRoleName(Map map){
    String roleName = (String)map.get("roleName");
    int roleId = (int)map.get("id");
    List checkedKeys = (List<Map>)map.get("checkedKeys");
    if (checkedKeys.size() > 0){
      adminDao.deleteRoleMenu(roleId);
      for (int i = 0; i < checkedKeys.size(); i++) {
        adminDao.insertRoleMenu(roleId,(int)checkedKeys.get(i));
      }
    }
    adminDao.updateRoleName(roleId,roleName);
  };

  public Map getMenuByRole(int roleId){
    List<MenuDto> list = adminDao.getMenuByRole(roleId);
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", list);
    return resultMap;
  };

  public Map getAllMenus(){
    List<MenuDto> list = adminDao.getMenuList();
    for (MenuDto menuDto: list){
      List<MenuDto> children = adminDao.getMenuListByParentId(menuDto.getMenuId());
      menuDto.setChildren(children);
    }
    Map<String, Object> resultMap = new HashMap<>();
    resultMap.put("result", list);
    return resultMap;
  }

  public void addNotice(String title,String content){
    adminDao.addNotice(title,content);
  }

  public Map getNotice(NoticeDto noticeDto){
    Map<String, Object> resultMap = new HashMap<>();
    List<NoticeDto> list;
    // 使用pageHelper分页
    PageHelper.startPage(noticeDto.getPage(),noticeDto.getPageSize(), "createDate desc");
    list = adminDao.getNotice(noticeDto);
    PageInfo<NoticeDto> pageInfo = new PageInfo<>(list);
    resultMap.put("result", pageInfo.getList());
    resultMap.put("total", pageInfo.getTotal());
    return resultMap;
  }

  public void updatePwd(Map pwdMap) throws Exception {
    log.info(pwdMap.toString());
    String oldpwd = (String)pwdMap.get("oldPwd");
    String newPwd = (String)pwdMap.get("newPwd");
    String username = getCurrentLoginUsername.getUsername();
    AccountDto accountDto =  accountDao.getUserByname(username);
    String encryptedPwd = DigestUtil.md5Hex(oldpwd);
    // 如果加密后的密码相同则执行更密码更新操作
    if (encryptedPwd.equals(accountDto.getPassword())){
      String encryptedNewPwd  = DigestUtil.md5Hex(newPwd);
      accountDao.updatePwd(username,encryptedNewPwd);
    } else {
      throw new Exception("旧密码不正确");
    }
  }

  public Map getAllComment(CommentsDto commentsDto) {
    Map<String, Object> resultMap = new HashMap<>();
    PageHelper.startPage(Integer.valueOf(commentsDto.getPageNum()),10);
    PageInfo<CommentsDto> pageInfo = new PageInfo<>(pagesDao.getAllComment());
    resultMap.put("total", pageInfo.getTotal());
    resultMap.put("result", pageInfo.getList());
    return resultMap;
  }

  public Object getListByTagsPage(String tag,String page){
    // 获取当前登录人
    String username = getCurrentLoginUsername.getUsername();
    Map<String, Object> resultMap = new HashMap<>();
    PageHelper.startPage(Integer.valueOf(page),10);
    List<PagesDto> list = pagesDao.getListByTags(tag, Integer.parseInt(page),username);
    PageInfo<PagesDto> pagesDtoPageInfo = new PageInfo<>(list);
    resultMap.put("total", pagesDtoPageInfo.getTotal());
    resultMap.put("result", pagesDtoPageInfo.getList());

    return resultMap;
  }
  ;
  public void approveComment(String id){
    adminDao.approveComment(id);
  }

  public void recoveryPost(String uid){
    adminDao.recoveryPost(uid);
  }
}